iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
Kubernetes

從零開始的 Kubernetes 基礎觀念與實作系列 第 27 篇

# 從零開始的 Kubernetes 基礎觀念與實作 DAY27

  • 分享至 

  • xImage
  •  

Kubernetes 綜合實作(一):建立應用程式

前面的文章已經介紹了 Kubernetes 中常見的資源,例如 Deployment、Service、ConfigMap、Secret,以及如何透過 YAML 管理這些資源。

不過,實際部署應用程式時,通常不會只使用單一資源,而是需要將多個資源組合起來。

接下來三篇將透過一個簡單的 Web API,逐步整合前面學過的 Kubernetes 功能。

這篇先完成以下工作:

  • 建立一個簡單的 Web API。
  • 使用 Docker 建立容器映像檔。
  • 透過 ConfigMap 和 Secret 提供應用程式設定。
  • 使用 Deployment 部署應用程式。
  • 透過 Service 存取應用程式。

建立 Web API

首先建立一個資料夾:

k8s-final-demo/
├── app.py
├── requirements.txt
├── Dockerfile
└── k8s/
    ├── configmap.yaml
    ├── secret.yaml
    ├── deployment.yaml
    └── service.yaml

這次使用 Python Flask 建立簡單的 HTTP API。

在 app.py 中加入:

from flask import Flask, jsonify
import os

app = Flask(__name__)

@app.route("/")
def index():
    return jsonify({
        "message": os.getenv("APP_MESSAGE", "Hello Kubernetes"),
        "version": "1.0"
    })

@app.route("/config")
def config():
    return jsonify({
        "app_name": os.getenv("APP_NAME", "demo"),
        "secret_configured": bool(os.getenv("APP_SECRET"))
    })

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

這個程式提供兩個 API:

  • /:回傳應用程式訊息與版本。
  • /config:確認環境變數是否成功載入。

其中 os.getenv() 可以取得環境變數,後續會透過 Kubernetes 的 ConfigMap 和 Secret 提供設定。

注意,/config 只回傳 Secret 是否存在,不會直接輸出 Secret 的內容。

接著建立 requirements.txt:

Flask==3.1.1

建立 Docker 映像檔

在專案根目錄建立 Dockerfile:

FROM python:3.13-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

EXPOSE 5000

CMD ["python", "app.py"]

接著執行:

docker build -t k8s-final-demo:1.0 .

建立完成後,可以透過以下指令查看映像檔:

docker images

image

由於是使用 Minikube,還需要將映像檔載入 Minikube:

minikube image load k8s-final-demo:1.0

如果使用多節點 Minikube,應確認映像檔已經載入可能執行 Pod 的節點。

建立 ConfigMap

ConfigMap 可以將應用程式設定與容器映像檔分開管理。

建立 k8s/configmap.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: final-demo-config
data:
  APP_NAME: "Kubernetes Final Demo"
  APP_MESSAGE: "Hello from ConfigMap"

這裡設定兩個環境變數:

  • APP_NAME:應用程式名稱。
  • APP_MESSAGE:API 回傳的訊息。

建立 Secret

Secret 可以用來保存密碼、Token 等敏感設定。

建立 k8s/secret.yaml:

apiVersion: v1
kind: Secret
metadata:
  name: final-demo-secret
type: Opaque
stringData:
  APP_SECRET: "demo-secret-123"

這裡使用 stringData,Kubernetes 會將內容轉換成 Secret 的資料格式。

這裡的 Secret 僅供本機實作使用。Kubernetes Secret 並不代表資料一定已加密儲存,正式環境應避免將真實密碼直接提交到版本控制系統,並考慮啟用 Secret 靜態加密及適當的 RBAC 權限控制。

建立 Deployment

接著建立 k8s/deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: final-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: final-demo
  template:
    metadata:
      labels:
        app: final-demo
    spec:
      containers:
        - name: web
          image: k8s-final-demo:1.0
          imagePullPolicy: Never
          ports:
            - containerPort: 5000
          envFrom:
            - configMapRef:
                name: final-demo-config
            - secretRef:
                name: final-demo-secret

這個 Deployment 主要包含:

  • replicas: 2:建立兩個 Pod 副本。
  • imagePullPolicy: Never:使用節點上已存在的映像檔。
  • containerPort: 5000:應用程式使用的 Port。
  • envFrom:將 ConfigMap 和 Secret 的資料載入容器環境變數。

這樣應用程式就不需要將設定直接寫在程式碼中。

建立 Service

Deployment 建立的 Pod 可能因為重新建立或排程而改變 IP,因此需要透過 Service 提供穩定的存取方式。

建立 k8s/service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: final-demo-service
spec:
  type: ClusterIP
  selector:
    app: final-demo
  ports:
    - port: 80
      targetPort: 5000

Service 會透過 Label Selector 找到具有 app: final-demo 的 Pod,並將流量轉送到容器的 5000 Port。

這裡先使用 ClusterIP,下一篇再透過 Ingress 提供對外存取方式。

部署應用程式

完成 YAML 後,在專案根目錄執行:

kubectl apply -f k8s/

接著查看 Deployment:

kubectl get deployments

image

查看 Pod:

kubectl get pods -o wide

image

查看 Service:

kubectl get svc

image

正常情況下,Deployment 應該建立兩個 Pod,並且都進入 Running 狀態。

如果 Pod 無法啟動,可以使用:

kubectl describe pod <pod-name>

查看 Events,確認是否發生映像檔不存在、資源不足或設定錯誤等問題。

測試 API

由於 Service 使用 ClusterIP,這裡透過 kubectl port-forward 從本機存取:

kubectl port-forward svc/final-demo-service 8080:80

接著開啟瀏覽器:

http://localhost:8080

會收到類似:
image

也可以測試:

http://localhost:8080/config

會回傳:

image

這代表應用程式成功讀取 ConfigMap 與 Secret 提供的環境變數。

觀察 Pod 與 Service 的關係

可以透過以下指令查看 Service 對應的 EndpointSlice:

kubectl get endpointslices -l kubernetes.io/service-name=final-demo-service

Service 會根據 Label Selector 找到符合條件的 Pod,並透過 EndpointSlice 記錄可用的後端端點。

由於 Deployment 設定了兩個副本,因此在兩個 Pod 都就緒的情況下,Service 可以將連線分配到不同的 Pod。

不過,這個範例的兩個 Pod 回傳相同內容,因此無法直接從 API 回應判斷請求被轉送到哪一個 Pod。

總結

這篇透過簡單的 Web API,整合了前面介紹過的 Deployment、Service、ConfigMap 和 Secret。

在這個範例中:

  • Deployment 負責管理應用程式的 Pod。
  • Service 提供穩定的網路存取方式。
  • ConfigMap 保存一般應用程式設定。
  • Secret 保存敏感設定。

這些資源共同組成一個簡單的 Kubernetes 應用程式。

目前應用程式還沒有資料持久化功能,Service 也只提供 Cluster 內部存取。

下一篇將在這個基礎上加入 Volume、PVC 和 Ingress,讓應用程式能夠保存資料,並透過 Ingress 存取服務。


上一篇
從零開始的 Kubernetes 基礎觀念與實作 DAY26
下一篇
# 從零開始的 Kubernetes 基礎觀念與實作 DAY28
系列文
從零開始的 Kubernetes 基礎觀念與實作 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言